Формирование модели монетизации

Шаг 1. Загрузка данных и подготовка их к анализу  

In [1]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import seaborn as sns
import datetime as dt
from scipy import stats as st
from plotly import graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots

Маркетинговые затраты   

In [2]:
ad_costs = pd.read_csv('datasets/ad_costs.csv')
In [3]:
ad_costs
Out[3]:
source day cost
0 facebook_ads 2020-05-03 935.882786
1 facebook_ads 2020-05-04 548.354480
2 facebook_ads 2020-05-05 260.185754
3 facebook_ads 2020-05-06 177.982200
4 facebook_ads 2020-05-07 111.766796
5 facebook_ads 2020-05-08 68.009276
6 facebook_ads 2020-05-09 38.723350
7 instagram_new_adverts 2020-05-03 943.204717
8 instagram_new_adverts 2020-05-04 502.925451
9 instagram_new_adverts 2020-05-05 313.970984
10 instagram_new_adverts 2020-05-06 173.071145
11 instagram_new_adverts 2020-05-07 109.915254
12 instagram_new_adverts 2020-05-08 71.578739
13 instagram_new_adverts 2020-05-09 46.775400
14 yandex_direct 2020-05-03 969.139394
15 yandex_direct 2020-05-04 554.651494
16 yandex_direct 2020-05-05 308.232990
17 yandex_direct 2020-05-06 180.917099
18 yandex_direct 2020-05-07 114.429338
19 yandex_direct 2020-05-08 62.961630
20 yandex_direct 2020-05-09 42.779505
21 youtube_channel_reklama 2020-05-03 454.224943
22 youtube_channel_reklama 2020-05-04 259.073224
23 youtube_channel_reklama 2020-05-05 147.041741
24 youtube_channel_reklama 2020-05-06 88.506074
25 youtube_channel_reklama 2020-05-07 55.740645
26 youtube_channel_reklama 2020-05-08 40.217907
27 youtube_channel_reklama 2020-05-09 23.314669
In [4]:
ad_costs.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 28 entries, 0 to 27
Data columns (total 3 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   source  28 non-null     object 
 1   day     28 non-null     object 
 2   cost    28 non-null     float64
dtypes: float64(1), object(2)
memory usage: 800.0+ bytes

Пропусков в данных нет, нужно изменить тип данных для дат:

In [5]:
ad_costs['day'] = ad_costs['day'].map(lambda x: dt.datetime.strptime(x, '%Y-%m-%d'))

Источники пользователей   

In [6]:
user_source = pd.read_csv('datasets/user_source.csv')
In [7]:
user_source
Out[7]:
user_id source
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 facebook_ads
1 00151b4f-ba38-44a8-a650-d7cf130a0105 yandex_direct
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa youtube_channel_reklama
3 001d39dc-366c-4021-9604-6a3b9ff01e25 instagram_new_adverts
4 002f508f-67b6-479f-814b-b05f00d4e995 facebook_ads
... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 instagram_new_adverts
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e facebook_ads
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 yandex_direct
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 instagram_new_adverts
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 facebook_ads

13576 rows × 2 columns

In [8]:
user_source.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 13576 entries, 0 to 13575
Data columns (total 2 columns):
 #   Column   Non-Null Count  Dtype 
---  ------   --------------  ----- 
 0   user_id  13576 non-null  object
 1   source   13576 non-null  object
dtypes: object(2)
memory usage: 212.2+ KB

Пользовательские действия в игре   

In [9]:
game_actions = pd.read_csv('datasets/game_actions.csv')
In [10]:
game_actions
Out[10]:
event_datetime event building_type user_id project_type
0 2020-05-04 00:00:01 building assembly_shop 55e92310-cb8e-4754-b622-597e124b03de NaN
1 2020-05-04 00:00:03 building assembly_shop c07b1c10-f477-44dc-81dc-ec82254b1347 NaN
2 2020-05-04 00:00:16 building assembly_shop 6edd42cc-e753-4ff6-a947-2107cd560710 NaN
3 2020-05-04 00:00:16 building assembly_shop 92c69003-d60a-444a-827f-8cc51bf6bf4c NaN
4 2020-05-04 00:00:35 building assembly_shop cdc6bb92-0ccb-4490-9866-ef142f09139d NaN
... ... ... ... ... ...
135635 2020-06-05 00:08:06 building research_center f21d179f-1c4b-437e-b9c6-ab1976907195 NaN
135636 2020-06-05 02:25:12 finished_stage_1 NaN 515c1952-99aa-4bca-a7ea-d0449eb5385a NaN
135637 2020-06-05 08:57:52 building research_center ed3e7d02-8a96-4be7-9998-e9813ff9c316 NaN
135638 2020-06-05 12:12:27 finished_stage_1 NaN 32572adb-900f-4b5d-a453-1eb1e6d88d8b NaN
135639 2020-06-05 12:32:49 finished_stage_1 NaN f21d179f-1c4b-437e-b9c6-ab1976907195 NaN

135640 rows × 5 columns

In [11]:
game_actions.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 135640 entries, 0 to 135639
Data columns (total 5 columns):
 #   Column          Non-Null Count   Dtype 
---  ------          --------------   ----- 
 0   event_datetime  135640 non-null  object
 1   event           135640 non-null  object
 2   building_type   127957 non-null  object
 3   user_id         135640 non-null  object
 4   project_type    1866 non-null    object
dtypes: object(5)
memory usage: 5.2+ MB

Проверим пропуски в данных и изменим тип данных для дат:

In [12]:
game_actions.isnull().sum()/game_actions.shape[0]*100
Out[12]:
event_datetime     0.000000
event              0.000000
building_type      5.664258
user_id            0.000000
project_type      98.624300
dtype: float64
In [13]:
game_actions.loc[game_actions['building_type'].isnull()]
Out[13]:
event_datetime event building_type user_id project_type
6659 2020-05-04 19:47:29 finished_stage_1 NaN ced7b368-818f-48f6-9461-2346de0892c5 NaN
13134 2020-05-05 13:22:09 finished_stage_1 NaN 7ef7fc89-2779-46ea-b328-9e5035b83af5 NaN
15274 2020-05-05 18:54:37 finished_stage_1 NaN 70db22b3-c2f4-43bc-94ea-51c8d2904a29 NaN
16284 2020-05-05 21:27:29 finished_stage_1 NaN 903fc9ef-ba97-4b12-9d5c-ac8d602fbd8b NaN
19650 2020-05-06 06:02:22 finished_stage_1 NaN 58e077ba-feb1-4556-a5a0-d96bd04efa39 NaN
... ... ... ... ... ...
135632 2020-06-04 15:50:38 finished_stage_1 NaN 22cce310-fe10-41a2-941b-9c3d63327fea NaN
135633 2020-06-04 17:56:14 finished_stage_1 NaN d477dde8-7c22-4f23-9c4f-4ec31a1aa4c8 NaN
135636 2020-06-05 02:25:12 finished_stage_1 NaN 515c1952-99aa-4bca-a7ea-d0449eb5385a NaN
135638 2020-06-05 12:12:27 finished_stage_1 NaN 32572adb-900f-4b5d-a453-1eb1e6d88d8b NaN
135639 2020-06-05 12:32:49 finished_stage_1 NaN f21d179f-1c4b-437e-b9c6-ab1976907195 NaN

7683 rows × 5 columns

Эти строки — пользователи, которые выбрали боевую стратегию и закончили уровень победой над врагом.

In [14]:
game_actions['project_type'].unique()
Out[14]:
array([nan, 'satellite_orbital_assembly'], dtype=object)
In [15]:
game_actions['event'].unique()
Out[15]:
array(['building', 'finished_stage_1', 'project'], dtype=object)
In [16]:
game_actions['event_datetime'] = pd.to_datetime(game_actions['event_datetime'], format='%Y-%m-%d')
In [17]:
game_actions
Out[17]:
event_datetime event building_type user_id project_type
0 2020-05-04 00:00:01 building assembly_shop 55e92310-cb8e-4754-b622-597e124b03de NaN
1 2020-05-04 00:00:03 building assembly_shop c07b1c10-f477-44dc-81dc-ec82254b1347 NaN
2 2020-05-04 00:00:16 building assembly_shop 6edd42cc-e753-4ff6-a947-2107cd560710 NaN
3 2020-05-04 00:00:16 building assembly_shop 92c69003-d60a-444a-827f-8cc51bf6bf4c NaN
4 2020-05-04 00:00:35 building assembly_shop cdc6bb92-0ccb-4490-9866-ef142f09139d NaN
... ... ... ... ... ...
135635 2020-06-05 00:08:06 building research_center f21d179f-1c4b-437e-b9c6-ab1976907195 NaN
135636 2020-06-05 02:25:12 finished_stage_1 NaN 515c1952-99aa-4bca-a7ea-d0449eb5385a NaN
135637 2020-06-05 08:57:52 building research_center ed3e7d02-8a96-4be7-9998-e9813ff9c316 NaN
135638 2020-06-05 12:12:27 finished_stage_1 NaN 32572adb-900f-4b5d-a453-1eb1e6d88d8b NaN
135639 2020-06-05 12:32:49 finished_stage_1 NaN f21d179f-1c4b-437e-b9c6-ab1976907195 NaN

135640 rows × 5 columns

Вывод:

Загрузили и обработали данные для дальнейшего анализа.

Шаг 2. Продукт  

Количество пользователей в день, неделю, месяц   

In [18]:
game_actions['session_year']  = game_actions['event_datetime'].dt.year
game_actions['session_month'] = game_actions['event_datetime'].astype('datetime64[M]')
game_actions['number_session_month'] = game_actions['event_datetime'].dt.month
game_actions['session_week']  = game_actions['event_datetime'].astype('datetime64[W]')
game_actions['number_session_week']  = game_actions['event_datetime'].dt.week
game_actions['session_date'] = game_actions['event_datetime'].dt.date
In [19]:
dau = game_actions.groupby('session_date').agg({'user_id': 'nunique'})
wau = game_actions.groupby(['session_year', 'number_session_week']).agg({'user_id': 'nunique'})
mau = game_actions.groupby(['session_year', 'number_session_month']).agg({'user_id': 'nunique'})
In [20]:
dau_total = dau.mean()
wau_total = wau.mean()
mau_total = mau.mean()
In [21]:
print('Уникальных пользователей в день:', int(dau_total))
print('Уникальных пользователей в неделю:', int(wau_total))
print('Уникальных пользователей в месяц:', int(mau_total))
Уникальных пользователей в день: 2884
Уникальных пользователей в неделю: 6120
Уникальных пользователей в месяц: 6802
In [22]:
dau.plot(grid=True, color = '#a52a2a',
         figsize=(16,8), label='Количество пользователей',
         legend=True, title='Количество уникальных пользователей в день');

Количество уникальных пользователей росло до 10 мая, а затем начало сокращаться.

In [23]:
wau.plot(kind='bar', grid=True, color = '#a52a2a',
         figsize=(16,8), label='Количество пользователей',
         legend=True, title='Количество уникальных пользователей в неделю');

В первые 2 недели количество уникальных пользователей было более 12000 человек, а затем сократилось более, чем в 2 раза.

In [24]:
mau.plot(kind='bar', grid=True, color = '#a52a2a',
         figsize=(16,8), label='Количество пользователей',
         legend=True, title='Количество уникальных пользователей в месяц');

У нас практически нет данных за июнь, поэтому сравнить количество уникальных пользователей в месяц не выйдет.

Количество сессий в день   

In [25]:
count_sessions = game_actions.groupby('session_date').agg({'user_id': 'count'})
In [26]:
count_sessions.plot(grid=True, color = '#a52a2a',
         figsize=(16,8), label='Количество пользователей', legend=True, title='Количество сессий в день');

Как и количество уникальных пользователей, количество сессий росло до 10 мая, а затем начало сильно снижаться.

In [27]:
count_sessions_mean = count_sessions.mean()
In [28]:
print('Количество сессий в день:', int(count_sessions_mean))
Количество сессий в день: 4110

Какие стратегии используются для завершения уровня   

In [29]:
event_users = (game_actions
               .groupby('event')
               .agg({'user_id':['count', 'nunique']})
               .sort_values(by=('user_id', 'count'), ascending=False)
               .reset_index())
In [30]:
event_users.columns = ['event', 'total_events', 'total_users']
In [31]:
event_users
Out[31]:
event total_events total_users
0 building 127957 13576
1 finished_stage_1 5817 5817
2 project 1866 1866

За указанный период 13576 пользователей успели построить 127957 объектов. 5817 пользователей закончили первый уровень, из них 1866 завершили проект.

Очередность построек   

In [32]:
building_users = (game_actions
               .groupby('building_type')
               .agg({'user_id':['count', 'nunique']})
               .sort_values(by=('user_id', 'count'), ascending=False)
               .reset_index())
In [33]:
building_users.columns = ['building_type', 'total_buildings', 'total_users']
In [34]:
building_users
Out[34]:
building_type total_buildings total_users
0 spaceport 59325 13231
1 assembly_shop 54494 13576
2 research_center 14138 7671

Объект spaceport был построен наибольшее количество раз (59325), assembly_shop был построен 54494 раз, а research_center построили только 14138 раз.

In [35]:
game_actions
Out[35]:
event_datetime event building_type user_id project_type session_year session_month number_session_month session_week number_session_week session_date
0 2020-05-04 00:00:01 building assembly_shop 55e92310-cb8e-4754-b622-597e124b03de NaN 2020 2020-05-01 5 2020-04-30 19 2020-05-04
1 2020-05-04 00:00:03 building assembly_shop c07b1c10-f477-44dc-81dc-ec82254b1347 NaN 2020 2020-05-01 5 2020-04-30 19 2020-05-04
2 2020-05-04 00:00:16 building assembly_shop 6edd42cc-e753-4ff6-a947-2107cd560710 NaN 2020 2020-05-01 5 2020-04-30 19 2020-05-04
3 2020-05-04 00:00:16 building assembly_shop 92c69003-d60a-444a-827f-8cc51bf6bf4c NaN 2020 2020-05-01 5 2020-04-30 19 2020-05-04
4 2020-05-04 00:00:35 building assembly_shop cdc6bb92-0ccb-4490-9866-ef142f09139d NaN 2020 2020-05-01 5 2020-04-30 19 2020-05-04
... ... ... ... ... ... ... ... ... ... ... ...
135635 2020-06-05 00:08:06 building research_center f21d179f-1c4b-437e-b9c6-ab1976907195 NaN 2020 2020-06-01 6 2020-06-04 23 2020-06-05
135636 2020-06-05 02:25:12 finished_stage_1 NaN 515c1952-99aa-4bca-a7ea-d0449eb5385a NaN 2020 2020-06-01 6 2020-06-04 23 2020-06-05
135637 2020-06-05 08:57:52 building research_center ed3e7d02-8a96-4be7-9998-e9813ff9c316 NaN 2020 2020-06-01 6 2020-06-04 23 2020-06-05
135638 2020-06-05 12:12:27 finished_stage_1 NaN 32572adb-900f-4b5d-a453-1eb1e6d88d8b NaN 2020 2020-06-01 6 2020-06-04 23 2020-06-05
135639 2020-06-05 12:32:49 finished_stage_1 NaN f21d179f-1c4b-437e-b9c6-ab1976907195 NaN 2020 2020-06-01 6 2020-06-04 23 2020-06-05

135640 rows × 11 columns

In [36]:
building_type = game_actions.groupby(['session_date', 'building_type'])['user_id'].count().reset_index()
In [37]:
building_type
Out[37]:
session_date building_type user_id
0 2020-05-04 assembly_shop 7767
1 2020-05-04 spaceport 403
2 2020-05-05 assembly_shop 7816
3 2020-05-05 spaceport 1236
4 2020-05-06 assembly_shop 7736
... ... ... ...
65 2020-06-03 research_center 3
66 2020-06-03 spaceport 4
67 2020-06-04 research_center 3
68 2020-06-04 spaceport 1
69 2020-06-05 research_center 2

70 rows × 3 columns

In [38]:
fig = px.line(building_type, x='session_date', y='user_id', color='building_type')
fig.update_layout(
    title='Распределение построек по времени',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show()

Первая постройка – assembly_shop. Вероятно, этот объект строится очень быстро и первый в очереди построек. Его построили максимальное количество пользователей, затем строились только другие объеты. Возможно, для первого уровня можно построить только 1 такой объект.

Объект research_center начали строить с задержкой, вероятно, он идёт последним для завершения уровня. Таким образом можно установить порядок строительства объектов: assembly_shop -> spaceport -> research_center

Также можно отметить, что с 13 мая активность построек упала по всем объектам: наверное, какие-то пользователи завершили уровень, а какие-то забросили игру.

Проверим, сколько времени пользователь провел в приложении:

In [39]:
first_visits = game_actions.groupby(['user_id'])['event_datetime'].min().reset_index()
first_visits.columns = ['user_id', 'first_visit']

last_visits = game_actions.groupby(['user_id'])['event_datetime'].max().reset_index()
last_visits.columns = ['user_id', 'last_visit']
In [40]:
duration_using = first_visits.merge(last_visits, on='user_id')
duration_using
Out[40]:
user_id first_visit last_visit
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 2020-05-06 01:07:37 2020-05-20 11:26:06
1 00151b4f-ba38-44a8-a650-d7cf130a0105 2020-05-06 03:09:12 2020-05-18 10:46:52
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa 2020-05-05 18:08:52 2020-05-14 09:21:27
3 001d39dc-366c-4021-9604-6a3b9ff01e25 2020-05-05 21:02:05 2020-05-12 07:40:47
4 002f508f-67b6-479f-814b-b05f00d4e995 2020-05-05 13:49:58 2020-05-22 02:46:45
... ... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 2020-05-04 01:58:59 2020-05-11 22:15:54
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e 2020-05-04 11:58:14 2020-05-14 10:11:36
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 2020-05-04 02:05:09 2020-05-12 13:01:52
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 2020-05-04 20:28:28 2020-05-11 22:04:30
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 2020-05-08 06:57:30 2020-05-25 14:05:51

13576 rows × 3 columns

In [41]:
duration_using['duration_days'] = (duration_using['last_visit'] - duration_using['first_visit']).dt.days
duration_using
Out[41]:
user_id first_visit last_visit duration_days
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 2020-05-06 01:07:37 2020-05-20 11:26:06 14
1 00151b4f-ba38-44a8-a650-d7cf130a0105 2020-05-06 03:09:12 2020-05-18 10:46:52 12
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa 2020-05-05 18:08:52 2020-05-14 09:21:27 8
3 001d39dc-366c-4021-9604-6a3b9ff01e25 2020-05-05 21:02:05 2020-05-12 07:40:47 6
4 002f508f-67b6-479f-814b-b05f00d4e995 2020-05-05 13:49:58 2020-05-22 02:46:45 16
... ... ... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 2020-05-04 01:58:59 2020-05-11 22:15:54 7
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e 2020-05-04 11:58:14 2020-05-14 10:11:36 9
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 2020-05-04 02:05:09 2020-05-12 13:01:52 8
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 2020-05-04 20:28:28 2020-05-11 22:04:30 7
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 2020-05-08 06:57:30 2020-05-25 14:05:51 17

13576 rows × 4 columns

In [42]:
print('Среднее количество дней в игре:', int(duration_using['duration_days'].mean()))
Среднее количество дней в игре: 10
In [43]:
fig = px.histogram(duration_using, x='duration_days')
fig.update_layout(
    barmode='stack',
    title='Количество дней, проведённых пользователями в игре',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show()

В среднем пользователь проводит в игре 10 дней.

Сколько времени занимает прохождение всего уровня для разных стратегий   

Теперь проверим, сколько времени пользователь тратит на построение объекта/завершение уровня:

In [44]:
events = game_actions[['user_id', 'event_datetime', 'event']]
In [45]:
users_strategy = game_actions[['user_id', 'project_type']].query('project_type == "satellite_orbital_assembly"')
In [46]:
duration_events = duration_using.merge(events, left_on=['user_id', 'last_visit'], right_on=['user_id', 'event_datetime'])              
In [47]:
duration_events =  duration_events.merge(users_strategy, how='left', on='user_id')
In [48]:
duration_events
Out[48]:
user_id first_visit last_visit duration_days event_datetime event project_type
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 2020-05-06 01:07:37 2020-05-20 11:26:06 14 2020-05-20 11:26:06 building NaN
1 00151b4f-ba38-44a8-a650-d7cf130a0105 2020-05-06 03:09:12 2020-05-18 10:46:52 12 2020-05-18 10:46:52 building NaN
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa 2020-05-05 18:08:52 2020-05-14 09:21:27 8 2020-05-14 09:21:27 building NaN
3 001d39dc-366c-4021-9604-6a3b9ff01e25 2020-05-05 21:02:05 2020-05-12 07:40:47 6 2020-05-12 07:40:47 finished_stage_1 NaN
4 002f508f-67b6-479f-814b-b05f00d4e995 2020-05-05 13:49:58 2020-05-22 02:46:45 16 2020-05-22 02:46:45 building NaN
... ... ... ... ... ... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 2020-05-04 01:58:59 2020-05-11 22:15:54 7 2020-05-11 22:15:54 finished_stage_1 NaN
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e 2020-05-04 11:58:14 2020-05-14 10:11:36 9 2020-05-14 10:11:36 building NaN
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 2020-05-04 02:05:09 2020-05-12 13:01:52 8 2020-05-12 13:01:52 finished_stage_1 NaN
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 2020-05-04 20:28:28 2020-05-11 22:04:30 7 2020-05-11 22:04:30 building NaN
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 2020-05-08 06:57:30 2020-05-25 14:05:51 17 2020-05-25 14:05:51 finished_stage_1 satellite_orbital_assembly

13576 rows × 7 columns

Пометим пользователей, которые выбрали боевую стратегию и закончили уровень победой над врагом, как 'fight'

In [49]:
duration_events['project_type'] = duration_events['project_type'].fillna('fight')
In [50]:
users_with_build_strategy = duration_events.query('project_type == "satellite_orbital_assembly"')
users_with_fight_strategy = duration_events.query('event == "finished_stage_1" and project_type == "fight"')
In [51]:
fig = go.Figure()

fig.add_trace(go.Histogram(x=users_with_build_strategy['duration_days'], name='build_strategy'))
fig.add_trace(go.Histogram(x=users_with_fight_strategy['duration_days'], name='fight_strategy'))
fig.update_layout(
    barmode='stack',
    title='Количество дней для завершения проекта',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.update_traces(opacity=0.75)
fig.show()

Пользователей, выбравших стратегию строительства, меньше и они в среднем тратят больше времени для прохождения уровня.

In [52]:
users_not_finished = duration_events.query('event == "building"')
In [53]:
fig = px.histogram(users_not_finished, x='duration_days')
fig.update_layout(
    barmode='stack',
    title='Количество дней в игре без завершения уровня',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show()

Пользователи, которые не завершили уровень, тратят в среднем 9 дней в игре.

In [54]:
build_strategy = (users_with_build_strategy
                    .pivot_table(index='event', values=['user_id', 'duration_days'], aggfunc={'user_id':'count', 'duration_days':'mean'})
                    .rename({'finished_stage_1':'users_with_build_strategy'}, axis=0))
In [55]:
build_strategy
Out[55]:
duration_days user_id
event
users_with_build_strategy 12.963023 1866
In [56]:
fight_strategy = (users_with_fight_strategy
                    .pivot_table(index='event', values=['user_id', 'duration_days'], aggfunc={'user_id':'count', 'duration_days':'mean'})
                    .rename({'finished_stage_1':'users_with_fight_strategy'}, axis=0))
In [57]:
without_strategy = (users_not_finished
                    .pivot_table(index='event', values=['user_id', 'duration_days'], aggfunc={'user_id':'count', 'duration_days':'mean'})
                    .rename({'building':'users_not_finished'}, axis=0))
In [58]:
all_strategies = pd.concat([build_strategy, fight_strategy, without_strategy])
In [59]:
all_strategies
Out[59]:
duration_days user_id
event
users_with_build_strategy 12.963023 1866
users_with_fight_strategy 10.606176 3951
users_not_finished 9.285475 7759
In [60]:
all_strategies['%_of_total'] = (all_strategies['user_id'] / all_strategies['user_id'].sum())*100
In [61]:
all_strategies
Out[61]:
duration_days user_id %_of_total
event
users_with_build_strategy 12.963023 1866 13.744844
users_with_fight_strategy 10.606176 3951 29.102829
users_not_finished 9.285475 7759 57.152328
In [62]:
fig = go.Figure()
fig.add_trace(go.Pie(values=all_strategies['%_of_total'], labels=all_strategies.index))
fig.update_layout(
    title='Статистика выбора стратегий',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show()

57% пользователей не перешли на другой уровень и играли в среднем около 9 дней.

29% пользователей выбрали боевую стратегию и среднее время прохождения этого уровня составило почти 11 дней.

И почти 13 дней потребовалось пользователям, которые продолжали строительство объектов.

Вывод:

В день в игру заходят 2884 уникальных пользователя, которые делают за это время 4110 действий. Рост пользователей и сессий наблюдался с 4 по 10 мая 2020 года, затем эти значения снижались.

С 4 мая по 5 июня 2020 года 13576 пользователей успели построить 127957 объектов. 5817 пользователей закончили первый уровень, из них 1866 завершили проект.

При выборе стратегии строительства пользователи строят объекты в следующем порядке: spaceport, assembly_shop, research_center. За указанное время объект spaceport был построен наибольшее количество раз (59325), assembly_shop был построен 54494 раз, а research_center построили только 14138 раз.

В среднем каждый пользователь провёл 10 дней в игре. Для завершения уровня потребуется в среднем от 11 (боевая стратегия) до 13 дней (стратегия строительства). Пользователи, которые не перешли на следующий уровень, (57% от общего числа) провели в игре 9 дней.

Шаг 3. Маркетинговые затраты  

Сколько в целом потратили на разные источники/в день   

In [63]:
ad_costs
Out[63]:
source day cost
0 facebook_ads 2020-05-03 935.882786
1 facebook_ads 2020-05-04 548.354480
2 facebook_ads 2020-05-05 260.185754
3 facebook_ads 2020-05-06 177.982200
4 facebook_ads 2020-05-07 111.766796
5 facebook_ads 2020-05-08 68.009276
6 facebook_ads 2020-05-09 38.723350
7 instagram_new_adverts 2020-05-03 943.204717
8 instagram_new_adverts 2020-05-04 502.925451
9 instagram_new_adverts 2020-05-05 313.970984
10 instagram_new_adverts 2020-05-06 173.071145
11 instagram_new_adverts 2020-05-07 109.915254
12 instagram_new_adverts 2020-05-08 71.578739
13 instagram_new_adverts 2020-05-09 46.775400
14 yandex_direct 2020-05-03 969.139394
15 yandex_direct 2020-05-04 554.651494
16 yandex_direct 2020-05-05 308.232990
17 yandex_direct 2020-05-06 180.917099
18 yandex_direct 2020-05-07 114.429338
19 yandex_direct 2020-05-08 62.961630
20 yandex_direct 2020-05-09 42.779505
21 youtube_channel_reklama 2020-05-03 454.224943
22 youtube_channel_reklama 2020-05-04 259.073224
23 youtube_channel_reklama 2020-05-05 147.041741
24 youtube_channel_reklama 2020-05-06 88.506074
25 youtube_channel_reklama 2020-05-07 55.740645
26 youtube_channel_reklama 2020-05-08 40.217907
27 youtube_channel_reklama 2020-05-09 23.314669
In [64]:
all_costs = ad_costs['cost'].sum()
all_costs
Out[64]:
7603.576986788022
In [65]:
costs_for_source = ad_costs.groupby('source').agg({'cost': 'sum'}).rename(columns={'cost':'total_costs'}).reset_index()
In [66]:
costs_for_source
Out[66]:
source total_costs
0 facebook_ads 2140.904643
1 instagram_new_adverts 2161.441691
2 yandex_direct 2233.111449
3 youtube_channel_reklama 1068.119204
In [67]:
costs_for_source.plot(kind='bar', x='source', y='total_costs', color = '#a52a2a', 
          figsize=(16,8), legend=True, title='Затраты на маркетинг по ресурсам');

Наибольшее количество средств было потрачено на привлечение пользователей через yandex_direct (2233). В 2 раза меньше средств было потрачено на youtube_channel_reklama (1068).

In [68]:
day_costs = ad_costs.groupby('day')['cost'].sum()
In [69]:
day_costs.plot(kind='bar', x='day', y='cost', color = '#a52a2a', 
          figsize=(16,8), legend=True, title='Затраты на маркетинг по дням');

Больше всего вложений было в первый день, 3 мая 2020. С каждым днём затраты на маркетинг значительно снижались.

Откуда люди приходят и столько это стоит   

In [70]:
user_source
Out[70]:
user_id source
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 facebook_ads
1 00151b4f-ba38-44a8-a650-d7cf130a0105 yandex_direct
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa youtube_channel_reklama
3 001d39dc-366c-4021-9604-6a3b9ff01e25 instagram_new_adverts
4 002f508f-67b6-479f-814b-b05f00d4e995 facebook_ads
... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 instagram_new_adverts
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e facebook_ads
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 yandex_direct
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 instagram_new_adverts
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 facebook_ads

13576 rows × 2 columns

In [71]:
users_sources = user_source.groupby('source').agg({'user_id':'nunique'}).rename(columns={'user_id':'users'})
In [72]:
users_sources
Out[72]:
users
source
facebook_ads 2726
instagram_new_adverts 3347
yandex_direct 4817
youtube_channel_reklama 2686
In [73]:
table_source = users_sources.merge(costs_for_source, on='source', how='outer')
In [74]:
table_source
Out[74]:
source users total_costs
0 facebook_ads 2726 2140.904643
1 instagram_new_adverts 3347 2161.441691
2 yandex_direct 4817 2233.111449
3 youtube_channel_reklama 2686 1068.119204
In [75]:
table_source['cac'] = table_source['total_costs'] / table_source['users']
In [76]:
table_source
Out[76]:
source users total_costs cac
0 facebook_ads 2726 2140.904643 0.785365
1 instagram_new_adverts 3347 2161.441691 0.645785
2 yandex_direct 4817 2233.111449 0.463590
3 youtube_channel_reklama 2686 1068.119204 0.397662
In [77]:
table_source.plot(kind='bar', x='source', y='cac', color = '#a52a2a', 
          figsize=(16,8), legend=True, title='Стоимость привлечения 1 пользователя по источникам');

Стоимость привлечения пользователя из facebook_ads выше, чем стоимость привлечения пользователей через другие ресурсы. Самым выгодным вложением стала реклама в youtube_channel_reklama, затраты на этот ресурс были самыми низкими, а пользователей в игру пришло много.

Посмотрим на этот показатель в динамике по источникам:

In [78]:
first_event = game_actions.groupby('user_id')['event_datetime'].min().reset_index()
first_event.columns = ['user_id', 'first_event_date']
In [79]:
first_event
Out[79]:
user_id first_event_date
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 2020-05-06 01:07:37
1 00151b4f-ba38-44a8-a650-d7cf130a0105 2020-05-06 03:09:12
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa 2020-05-05 18:08:52
3 001d39dc-366c-4021-9604-6a3b9ff01e25 2020-05-05 21:02:05
4 002f508f-67b6-479f-814b-b05f00d4e995 2020-05-05 13:49:58
... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 2020-05-04 01:58:59
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e 2020-05-04 11:58:14
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 2020-05-04 02:05:09
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 2020-05-04 20:28:28
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 2020-05-08 06:57:30

13576 rows × 2 columns

In [80]:
first_event['day'] = first_event['first_event_date'].astype('datetime64[D]')
In [81]:
source_users = user_source.merge(first_event, on='user_id', how='inner')
In [82]:
source_users
Out[82]:
user_id source first_event_date day
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 facebook_ads 2020-05-06 01:07:37 2020-05-06
1 00151b4f-ba38-44a8-a650-d7cf130a0105 yandex_direct 2020-05-06 03:09:12 2020-05-06
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa youtube_channel_reklama 2020-05-05 18:08:52 2020-05-05
3 001d39dc-366c-4021-9604-6a3b9ff01e25 instagram_new_adverts 2020-05-05 21:02:05 2020-05-05
4 002f508f-67b6-479f-814b-b05f00d4e995 facebook_ads 2020-05-05 13:49:58 2020-05-05
... ... ... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 instagram_new_adverts 2020-05-04 01:58:59 2020-05-04
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e facebook_ads 2020-05-04 11:58:14 2020-05-04
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 yandex_direct 2020-05-04 02:05:09 2020-05-04
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 instagram_new_adverts 2020-05-04 20:28:28 2020-05-04
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 facebook_ads 2020-05-08 06:57:30 2020-05-08

13576 rows × 4 columns

In [83]:
source_users_costs = source_users.merge(ad_costs, on=['source', 'day'], how='outer')
In [84]:
source_users_costs
Out[84]:
user_id source first_event_date day cost
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 facebook_ads 2020-05-06 01:07:37 2020-05-06 177.982200
1 01303c2e-7de1-4742-8c3e-daf182b67b9f facebook_ads 2020-05-06 07:05:11 2020-05-06 177.982200
2 0136963c-c45c-4edb-92d8-205bd50a4d36 facebook_ads 2020-05-06 14:00:20 2020-05-06 177.982200
3 018793d6-38c8-450a-bd54-8c181d920f1a facebook_ads 2020-05-06 07:05:52 2020-05-06 177.982200
4 01e2b256-4519-493f-b010-4a90a2755245 facebook_ads 2020-05-06 22:16:07 2020-05-06 177.982200
... ... ... ... ... ...
13575 ff77733a-62a1-4d5b-9eb5-034222f24609 yandex_direct 2020-05-08 22:53:20 2020-05-08 62.961630
13576 NaN facebook_ads NaT 2020-05-03 935.882786
13577 NaN instagram_new_adverts NaT 2020-05-03 943.204717
13578 NaN yandex_direct NaT 2020-05-03 969.139394
13579 NaN youtube_channel_reklama NaT 2020-05-03 454.224943

13580 rows × 5 columns

In [85]:
cost_per_user_in_day = source_users_costs.groupby(['source', 'day']).agg({'user_id':'nunique', 'cost':'max'})
In [86]:
cost_per_user_in_day['cac'] = cost_per_user_in_day['cost'] / cost_per_user_in_day['user_id']
In [87]:
cost_per_user_in_day
Out[87]:
user_id cost cac
source day
facebook_ads 2020-05-03 0 935.882786 inf
2020-05-04 1184 548.354480 0.463137
2020-05-05 694 260.185754 0.374907
2020-05-06 345 177.982200 0.515890
2020-05-07 224 111.766796 0.498959
2020-05-08 139 68.009276 0.489275
2020-05-09 84 38.723350 0.460992
2020-05-10 56 NaN NaN
instagram_new_adverts 2020-05-03 0 943.204717 inf
2020-05-04 1452 502.925451 0.346367
2020-05-05 796 313.970984 0.394436
2020-05-06 472 173.071145 0.366676
2020-05-07 270 109.915254 0.407094
2020-05-08 175 71.578739 0.409021
2020-05-09 112 46.775400 0.417637
2020-05-10 70 NaN NaN
yandex_direct 2020-05-03 0 969.139394 inf
2020-05-04 2078 554.651494 0.266916
2020-05-05 1208 308.232990 0.255160
2020-05-06 664 180.917099 0.272466
2020-05-07 395 114.429338 0.289695
2020-05-08 239 62.961630 0.263438
2020-05-09 144 42.779505 0.297080
2020-05-10 89 NaN NaN
youtube_channel_reklama 2020-05-03 0 454.224943 inf
2020-05-04 1146 259.073224 0.226067
2020-05-05 663 147.041741 0.221782
2020-05-06 366 88.506074 0.241820
2020-05-07 220 55.740645 0.253367
2020-05-08 135 40.217907 0.297910
2020-05-09 100 23.314669 0.233147
2020-05-10 56 NaN NaN
In [88]:
fig = go.Figure()
fig.add_trace(go.Bar(
    x=cost_per_user_in_day.loc['facebook_ads'].index,
    y=cost_per_user_in_day.loc['facebook_ads']['cac'],
    name='facebook_ads',
    marker_color='indianred'
))
fig.add_trace(go.Bar(
    x=cost_per_user_in_day.loc['instagram_new_adverts'].index,
    y=cost_per_user_in_day.loc['instagram_new_adverts']['cac'],
    name='instagram_new_adverts',
    marker_color='lightsalmon'
))
fig.add_trace(go.Bar(
    x=cost_per_user_in_day.loc['yandex_direct'].index,
    y=cost_per_user_in_day.loc['yandex_direct']['cac'],
    name='yandex_direct',
    marker_color='maroon'
))
fig.add_trace(go.Bar(
    x=cost_per_user_in_day.loc['youtube_channel_reklama'].index,
    y=cost_per_user_in_day.loc['youtube_channel_reklama']['cac'],
    name='youtube_channel_reklama',
    marker_color='rebeccapurple'
))

fig.update_layout(
    barmode='group',
    title='Затраты на привлечение 1 пользователя по источникам в динамике',
    title_x = 0.5,
    margin=dict(l=50, r=50, t=130, b=50))
fig.show()

Стоимость привлечения 1 пользователя через youtube_channel_reklama практически во все дни рекламной компании была самой низкой. Дороже всего обходился пользователь из facebook_ads.

Сколько нужно заработать, чтобы окупить расходы   

Будем использовать известный принцим для расчета оптимального соотношения LTV и CAC:

1:1 или меньше — бизнес обречен на провал, если срочно не улучшить ситуацию;

2:1 — затраты на привлечение клиентов практически не окупаются;

3:1 — бизнес-модель работает продуктивно: именно такое соотношение можно назвать оптимальным, к нему нужно стремиться;

4:1 — ваш бизнес очень продуктивный — клиенты стоят недорого и приносят компании хорошую прибыль.

In [89]:
table_source
Out[89]:
source users total_costs cac
0 facebook_ads 2726 2140.904643 0.785365
1 instagram_new_adverts 3347 2161.441691 0.645785
2 yandex_direct 4817 2233.111449 0.463590
3 youtube_channel_reklama 2686 1068.119204 0.397662
In [90]:
table_source['good_revenue'] = table_source['cac'] * 3
In [91]:
table_source
Out[91]:
source users total_costs cac good_revenue
0 facebook_ads 2726 2140.904643 0.785365 2.356095
1 instagram_new_adverts 3347 2161.441691 0.645785 1.937354
2 yandex_direct 4817 2233.111449 0.463590 1.390769
3 youtube_channel_reklama 2686 1068.119204 0.397662 1.192985
In [92]:
table_source['price_per_ad'] = table_source['good_revenue']/2
In [93]:
table_source
Out[93]:
source users total_costs cac good_revenue price_per_ad
0 facebook_ads 2726 2140.904643 0.785365 2.356095 1.178047
1 instagram_new_adverts 3347 2161.441691 0.645785 1.937354 0.968677
2 yandex_direct 4817 2233.111449 0.463590 1.390769 0.695385
3 youtube_channel_reklama 2686 1068.119204 0.397662 1.192985 0.596492

Вывод:

На привлечение пользователей с 3 по 9 мая 2020 года потратили 7603. Наибольшая сумма затрат была у источника yandex_direct (2233), а меньше всего средств потратили на привлечение через youtube_channel_reklama (1068).

Значительная сумма была потрачена в первый день компании, затем расходы постепенно снижались.

Больше всего пользователей пришло из yandex_direct (4817), а дешевле всего обошёлся пользователь из youtube_channel_reklama.

Для того, чтобы покрыть затраты на привлечение, нужно встраивать рекламу, которая будет приносить в 3 раза больше, чем мы потратили на привлечение пользователя. В каждом из источников стоит выставить свои ограничения.

Шаг 4. Проверка гипотез  

Время прохождения уровня в зависимости от стратегии   

Нулевая — пользователи, которые выбирают боевую стратегию, тратят столько же времени, сколько и те, кто строит спутники. Альтернативная — затраченное время у пользователей, выбравших разные стратегии, отличается.

In [94]:
alpha = 0.05
In [95]:
results = st.ttest_ind(users_with_build_strategy['duration_days'], users_with_fight_strategy['duration_days'], equal_var = False)
print('p-значение: ', results.pvalue)

if (results.pvalue < alpha):
    print("Отвергаем нулевую гипотезу, различие между пользователями есть")
else:
    print("Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет")
p-значение:  2.6237027268064204e-106
Отвергаем нулевую гипотезу, различие между пользователями есть

Затраченное время у пользователей, выбравших разные стратегии, отличается. По нашим расчётам пользователям, выбравшим боевую стратегию требуется в среднем 11 дней. А пользователям, которые завершили уровень с помощью постройки объектов, тратят на прохождение уровня 13 дней.

Время прохождения уровня в зависимости от рекламного источника   

Нулевая — пользователи, привлеченные из одного рекламного источника, тратят столько же времени для прохождения уровня, сколько и пользователи, привлеченные из другого источника.

Альтернативная — время, которое для завершения уровня потратили пользователи, привлеченные из одного рекламного источника, отличается от времени, которое потратили пользователи из другого рекламного источника.

In [96]:
duration_using = duration_using.merge(user_source, on='user_id', how='left')
In [97]:
duration_using
Out[97]:
user_id first_visit last_visit duration_days source
0 0001f83c-c6ac-4621-b7f0-8a28b283ac30 2020-05-06 01:07:37 2020-05-20 11:26:06 14 facebook_ads
1 00151b4f-ba38-44a8-a650-d7cf130a0105 2020-05-06 03:09:12 2020-05-18 10:46:52 12 yandex_direct
2 001aaea6-3d14-43f1-8ca8-7f48820f17aa 2020-05-05 18:08:52 2020-05-14 09:21:27 8 youtube_channel_reklama
3 001d39dc-366c-4021-9604-6a3b9ff01e25 2020-05-05 21:02:05 2020-05-12 07:40:47 6 instagram_new_adverts
4 002f508f-67b6-479f-814b-b05f00d4e995 2020-05-05 13:49:58 2020-05-22 02:46:45 16 facebook_ads
... ... ... ... ... ...
13571 ffef4fed-164c-40e1-bde1-3980f76d0fb5 2020-05-04 01:58:59 2020-05-11 22:15:54 7 instagram_new_adverts
13572 fffab3da-da0e-4e30-ae62-10d0a2e24a4e 2020-05-04 11:58:14 2020-05-14 10:11:36 9 facebook_ads
13573 fffb626c-5ab6-47c9-8113-2062a2f18494 2020-05-04 02:05:09 2020-05-12 13:01:52 8 yandex_direct
13574 ffff194a-56b7-4c12-860d-3485242ae7f5 2020-05-04 20:28:28 2020-05-11 22:04:30 7 instagram_new_adverts
13575 ffff69cc-fec1-4fd3-9f98-93be1112a6b8 2020-05-08 06:57:30 2020-05-25 14:05:51 17 facebook_ads

13576 rows × 5 columns

In [98]:
facebook = duration_using[['source', 'duration_days']].query('source == "facebook_ads"')
instagram = duration_using[['source', 'duration_days']].query('source == "instagram_new_adverts"')
yandex_direct = duration_using[['source', 'duration_days']].query('source == "yandex_direct"')
youtube_channel_reklama = duration_using[['source', 'duration_days']].query('source == "youtube_channel_reklama"')

Чтобы снизить групповую вероятность ошибки первого рода, можно использовать метод Шидака (он повысит мощность теста) или Бенферони. Будем использовать метод Шидака:

In [99]:
def st_test (group_1, group_2, alpha):
    results = st.ttest_ind(group_1['duration_days'], group_2['duration_days'], equal_var = False)
    print('p-значение: ', results.pvalue)
    if (results.pvalue < alpha):
        print("Отвергаем нулевую гипотезу, различие между пользователями есть")
    else:
        print("Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет") 
In [100]:
shidak_alpha = [1 - (1 - alpha)**(1/m) for m in range(1, 7)]
In [101]:
shidak_alpha
Out[101]:
[0.050000000000000044,
 0.025320565519103666,
 0.016952427508441503,
 0.012741455098566168,
 0.010206218313011495,
 0.008512444610847103]
In [102]:
st_test(facebook, instagram, shidak_alpha[0])
st_test(facebook, yandex_direct, shidak_alpha[1])
st_test(facebook, youtube_channel_reklama, shidak_alpha[2])
st_test(instagram, yandex_direct, shidak_alpha[3])
st_test(instagram, youtube_channel_reklama, shidak_alpha[4])
st_test(yandex_direct, youtube_channel_reklama, shidak_alpha[5])
p-значение:  0.5529958757362929
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет
p-значение:  0.3292177831704628
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет
p-значение:  0.22744523023390675
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет
p-значение:  0.08538226072643314
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет
p-значение:  0.06360629144309526
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет
p-значение:  0.6933048123346999
Не получилось отвергнуть нулевую гипотезу, различия между пользователями нет

Гипотезу отвергнуть не получилось, статистически значимых различий во времени прохождения уровня между пользователями из разных источников трафика нет.

Вывод:

Время прохождения уровня зависит от выбранной стратегии, но не зависит от рекламного источника, через который пришёл пользователь.

Шаг 5. Выводы  

Большая часть пользователей (57%) не заканчивают уровень и тратят на игру в среднем 9 дней. Возможно, стоит упростить какие-то этапы, чтобы пользователи не отваливались так рано.

Время прохождения уровня отличается у пользователей, выбравших разные стратегии. Быстрее всего удаётся пройти уровень пользователям с боевой стратегией. 29% пользователей выбрали боевую стратегию. Возможно, вариант строительства объектов слишком затянут и стоит перепридумать ход игры.

Что касается монетизации, то рекламу точно стоит показывать до завершения уровня, ведь к этому этапу не доходят 57% пользователей.

  • Объект spaceport был построен наибольшее количество раз (59325), assembly_shop был построен 54494 раз, а research_center построили только 14138 раз. Вероятно, постройка research_center длится очень долго или требует каких-то дополнительных действий и ресурсов. Хорошим вариантом было бы показывать рекламу, чтобы ускорить процесс строительства (например, если смотреть рекламу, то прогресс строительства идёт быстрее).

Выбор стоимости показа рекламы стоит осуществлять исходя из cac. Для того чтобы получить прибыль, стоит закладывать стоимость показа в 3 раза выше, чем стоимость привлечения одного пользователя. Практически все пользователи строят первые 2 объекта, поэтому можно показывать рекламу перед выбором постройки стоимостью в 1,5 раза выше, чем стоимость привлечения пользователя.

In [ ]: